syntax = "proto3";

package kuma.mesh.v1alpha1;

option go_package = "github.com/kumahq/kuma/api/mesh/v1alpha1";

import "api/mesh/options.proto";
import "api/mesh/v1alpha1/selector.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "validate/validate.proto";
import "kuma-doc/config.proto";

option (doc.config) = {
  type : Policy,
  name : "HealthCheck",
  file_name : "health-check"
};

// HealthCheck defines configuration for health checking.
message HealthCheck {

  option (kuma.mesh.resource).name = "HealthCheckResource";
  option (kuma.mesh.resource).type = "HealthCheck";
  option (kuma.mesh.resource).package = "mesh";
  option (kuma.mesh.resource).kds.send_to_zone = true;
  option (kuma.mesh.resource).ws.name = "health-check";
  option (kuma.mesh.resource).allow_to_inspect = true;

  // List of selectors to match dataplanes that should be configured to do
  // health checks.
  repeated Selector sources = 1
      [ (validate.rules).repeated .min_items = 1, (doc.required) = true ];

  // List of selectors to match services that need to be health checked.
  repeated Selector destinations = 2
      [ (validate.rules).repeated .min_items = 1, (doc.required) = true ];

  // Conf defines configuration for various types of health checking.
  message Conf {
    // Interval between consecutive health checks.
    google.protobuf.Duration interval = 1 [
      (validate.rules).duration = {
        required : true,
        gt {}
      },
      (doc.required) = true
    ];

    // Maximum time to wait for a health check response.
    google.protobuf.Duration timeout = 2 [
      (validate.rules).duration = {
        required : true,
        gt {}
      },
      (doc.required) = true
    ];

    // Number of consecutive unhealthy checks before considering a host
    // unhealthy.
    uint32 unhealthy_threshold = 3
        [ (validate.rules).uint32 = {gt : 0}, (doc.required) = true ];

    // Number of consecutive healthy checks before considering a host healthy.
    uint32 healthy_threshold = 4
        [ (validate.rules).uint32 = {gt : 0}, (doc.required) = true ];

    // If specified, Envoy will start health checking after for a random time in
    // ms between 0 and initial_jitter. This only applies to the first health
    // check.
    google.protobuf.Duration initial_jitter = 7;

    // If specified, during every interval Envoy will add interval_jitter to the
    // wait time.
    google.protobuf.Duration interval_jitter = 8;

    // If specified, during every interval Envoy will add interval_ms *
    // interval_jitter_percent / 100 to the wait time. If interval_jitter_ms and
    // interval_jitter_percent are both set, both of them will be used to
    // increase the wait time.
    uint32 interval_jitter_percent = 9;

    // Allows to configure panic threshold for Envoy cluster. If not specified,
    // the default is 50%. To disable panic mode, set to 0%.
    google.protobuf.FloatValue healthy_panic_threshold = 10;

    // If set to true, Envoy will not consider any hosts when the cluster is in
    // 'panic mode'. Instead, the cluster will fail all requests as if all hosts
    // are unhealthy. This can help avoid potentially overwhelming a failing
    // service.
    google.protobuf.BoolValue fail_traffic_on_panic = 11;

    // Specifies the path to the file where Envoy can log health check events.
    // If empty, no event log will be written.
    string event_log_path = 12;

    // If set to true, health check failure events will always be logged. If set
    // to false, only the initial health check failure event will be logged. The
    // default value is false.
    google.protobuf.BoolValue always_log_health_check_failures = 13;

    // The "no traffic interval" is a special health check interval that is used
    // when a cluster has never had traffic routed to it. This lower interval
    // allows cluster information to be kept up to date, without sending a
    // potentially large amount of active health checking traffic for no reason.
    // Once a cluster has been used for traffic routing, Envoy will shift back
    // to using the standard health check interval that is defined. Note that
    // this interval takes precedence over any other. The default value for "no
    // traffic interval" is 60 seconds.
    google.protobuf.Duration no_traffic_interval = 14;

    // Tcp defines optional configuration for specifying bytes to send and
    // expected response during the health check
    message Tcp {
      // Bytes which will be send during the health check to the target
      google.protobuf.BytesValue send = 1;

      // Bytes blocks expected as a response. When checking the response,
      // “fuzzy” matching is performed such that each block must be found, and
      // in the order specified, but not necessarily contiguous.
      repeated google.protobuf.BytesValue receive = 2;
    }

    // Http defines optional Http configuration which will instruct the service
    // the health check will be made for is an http service. It's mutually
    // exclusive with the Tcp block so when provided you can't provide
    // the Tcp configuration
    message Http {
      // The HTTP path which will be requested during the health check
      // (ie. /health)
      //  +required
      string path = 1 [ (doc.required) = true ];

      message HeaderValue {
        // Header name
        //  +required
        string key = 1 [ (doc.required) = true ];
        // Header value
        //  +optional
        string value = 2;
      }

      message HeaderValueOption {
        // Key/Value representation of the HTTP header
        //  +required
        HeaderValue header = 1 [ (doc.required) = true ];
        // The bool value which if true (default) will mean the header values
        // should be appended to already present ones
        //  +optional
        google.protobuf.BoolValue append = 2;
      }

      // The list of HTTP headers which should be added to each health check
      // request
      //  +optional
      repeated HeaderValueOption request_headers_to_add = 2;

      // List of HTTP response statuses which are considered healthy
      //  +optional
      repeated google.protobuf.UInt32Value expected_statuses = 3
          [ (validate.rules).uint32 = {gte : 100, lt : 600} ];
    }

    Tcp tcp = 5;
    Http http = 6;

    // Reuse health check connection between health checks. Default is true.
    google.protobuf.BoolValue reuse_connection = 15;
  }

  // Configuration for various types of health checking.
  Conf conf = 3 [ (doc.required) = true ];
}
